www.gusucode.com > VC++ 解析emf文件结构并显示-源码程序 > VC++ 解析emf文件结构并显示-源码程序/code/EmfReader/EmfRecordFuns.cpp

    //Download by http://www.NewXing.com
#include "Stdafx.h"
#include "EmfReaderDlg.h"
#include "Wingdi.h"
void CEmfReaderDlg::EmrSelectObject( LPBYTE lpData,BOOL bDeleteFlag  )
{
	PEMRSELECTOBJECT pSelectObj ;
	pSelectObj = (PEMRSELECTOBJECT)lpData ;

	CString strObjName = L"Other" ;
	if( pSelectObj->ihObject >= 0x80000000 )
	{
		switch( pSelectObj->ihObject & 0xff )
		{
		case WHITE_BRUSH :
			strObjName = L"WHITE_BRUSH" ;
			break ;
		case LTGRAY_BRUSH :
			strObjName = L"LTGRAY_BRUSH" ;
			break ;
		case GRAY_BRUSH :
			strObjName = L"GRAY_BRUSH" ;
			break ;
		case DKGRAY_BRUSH :
			strObjName = L"DKGRAY_BRUSH" ;
			break ;
		case BLACK_BRUSH :
			strObjName = L"BLACK_BRUSH" ;
			break ;
		case NULL_BRUSH :
			strObjName = L"NULL_BRUSH" ;
			break ;
		case WHITE_PEN :
			strObjName = L"WHITE_PEN" ;
			break ;
		case BLACK_PEN :
			strObjName = L"BLACK_PEN" ;
			break ;
		case NULL_PEN :
			strObjName = L"NULL_PEN" ;
			break ;
		case OEM_FIXED_FONT :
			strObjName = L"OEM_FIXED_FONT" ;
			break ;
		case ANSI_FIXED_FONT :
			strObjName = L"ANSI_FIXED_FONT" ;
			break ;
		case ANSI_VAR_FONT :
			strObjName = L"ANSI_VAR_FONT" ;
			break ;
		case SYSTEM_FONT :
			strObjName = L"SYSTEM_FONT" ;
			break ;
		case DEVICE_DEFAULT_FONT :
			strObjName = L"DEVICE_DEFAULT_FONT" ;
			break ;
		case DEFAULT_PALETTE :
			strObjName = L"DEFAULT_PALETTE" ;
			break ;
		case SYSTEM_FIXED_FONT :
			strObjName = L"SYSTEM_FIXED_FONT" ;
			break ;
		default:
			strObjName.Format(L"0x%08x" , pSelectObj->ihObject ) ;
		}
	}
	else
	{
		strObjName.Format(L"0x%08x" , pSelectObj->ihObject ) ;
	}

	BOOL bFound = FALSE ;
	if( pSelectObj->ihObject < 0x80000000 )
	{
		for( list<HGDIOBJECT_NODE>::iterator it = m_listGdiObj.begin() ; it != m_listGdiObj.end() ; it++) 
		{
			HGDIOBJECT_NODE node = (HGDIOBJECT_NODE)(*it) ;
			if( node.dwIndex == pSelectObj->ihObject )
			{
				if( bDeleteFlag )
				{
					m_listGdiObj.erase( it ) ;
					DeleteObject( node.hGidObj ) ;
				}
				else
				{
					SelectObject( m_hDCMem , node.hGidObj ) ;
				}
				strObjName = node.szDescript ;
				bFound = TRUE ;
				break ;
			}
		}
	}
	if(!bFound)
	{
		HGDIOBJ hObj = GetStockObject( pSelectObj->ihObject & 0xFF  ) ;
		if( hObj && !bDeleteFlag)
		{
			SelectObject( m_hDCMem , hObj ) ;
		}
	}
	TRACE(L"EmrSelectObject:%s,%s\n",strObjName ,bDeleteFlag ? L"delete":L"");
}
void CEmfReaderDlg::EmrPolyX( LPBYTE lpData)
{
	PEMRPOLYBEZIER pPolyBezier ;
	pPolyBezier = (PEMRPOLYBEZIER)lpData ;
	switch( pPolyBezier->emr.iType )
	{
	case EMR_POLYLINE:
		Polyline( m_hDCMem , (POINT *)(&pPolyBezier->aptl) , pPolyBezier->cptl ) ;
		TRACE("EmrPolyLine,count:%ld\n" , pPolyBezier->cptl );
		break ;
	case EMR_POLYBEZIER :
		PolyBezier( m_hDCMem , (POINT *)(&pPolyBezier->aptl) , pPolyBezier->cptl ) ;
		TRACE("EmrPolyLineBezier,count:%ld\n" , pPolyBezier->cptl );
		break ;
	case EMR_POLYGON:
		Polygon( m_hDCMem ,(POINT *)(&pPolyBezier->aptl) , pPolyBezier->cptl ) ;
		TRACE("EmrPolyLineGon,count:%ld\n" , pPolyBezier->cptl );
		break ;
	case EMR_POLYBEZIERTO:
		PolyBezierTo(m_hDCMem , (POINT *)(&pPolyBezier->aptl) , pPolyBezier->cptl ) ;
		TRACE("EmrPolyLineBezierTo,count:%ld\n" , pPolyBezier->cptl );
		break ;
	case EMR_POLYLINETO:
		Polyline( m_hDCMem ,(POINT *)(&pPolyBezier->aptl) , pPolyBezier->cptl ) ;
		TRACE("EmrPolyLineTo,count:%ld\n" , pPolyBezier->cptl );
		break ;
	}
}
void CEmfReaderDlg::EmrPoly16X( LPBYTE lpData)
{
	PEMRPOLYLINE16 pPolyBezier ;
	pPolyBezier = (PEMRPOLYLINE16)lpData ;
	POINT *pt = NULL ;
	if( pPolyBezier->cpts > 0 )
	{
		pt = new POINT[pPolyBezier->cpts] ;
		for( long lIndex = 0 ; lIndex < (long)pPolyBezier->cpts ; lIndex ++ )
		{
			pt[lIndex].x =  pPolyBezier->apts[lIndex].x ;
			pt[lIndex].y =  pPolyBezier->apts[lIndex].y ;
		}
	}
	switch( pPolyBezier->emr.iType )
	{
	case EMR_POLYLINE16:
		Polyline( m_hDCMem ,pt , pPolyBezier->cpts ) ;
		TRACE("EmrPolyLine16,count:%ld\n" , pPolyBezier->cpts );
		break ;
	case EMR_POLYBEZIER16 :
		PolyBezier( m_hDCMem ,pt , pPolyBezier->cpts ) ;
		TRACE("EmrPolyLineBezier16,count:%ld\n" , pPolyBezier->cpts );
		break ;
	case EMR_POLYGON16:
		Polygon( m_hDCMem ,pt, pPolyBezier->cpts ) ;
		TRACE("EmrPolyLineGon16,count:%ld\n" , pPolyBezier->cpts );
		break ;
	case EMR_POLYBEZIERTO16:
		PolyBezierTo( m_hDCMem ,pt , pPolyBezier->cpts ) ;
		TRACE("EmrPolyLineBezierTo16,count:%ld\n" , pPolyBezier->cpts );
		break ;
	case EMR_POLYLINETO16:
		PolylineTo( m_hDCMem ,pt, pPolyBezier->cpts ) ;
		TRACE("EmrPolyLineTo16,count:%ld\n" , pPolyBezier->cpts );
		break ;
	}
	if( pt )
		delete pt ;
}
void CEmfReaderDlg::EmrBitBlt( LPBYTE lpData)
{
	PEMRBITBLT pBitBlt ;
	pBitBlt = (PEMRBITBLT)lpData ;
	if( pBitBlt->offBmiSrc > 0 )
	{

		PBITMAPINFO pBitmapInfo = (PBITMAPINFO)( lpData + pBitBlt->offBmiSrc ) ; 
		BOOL bRet = StretchDIBits( m_hDCMem , pBitBlt->xDest , pBitBlt->yDest , pBitBlt->cxDest , pBitBlt->cyDest , 
			pBitBlt->xSrc , pBitBlt->ySrc , pBitBlt->cxDest , pBitBlt->cyDest ,
			lpData + pBitBlt->offBitsSrc , 
			pBitmapInfo , 
			pBitBlt->iUsageSrc ,pBitBlt->dwRop ) ;
	}
	else
	{
		RECT rc ;
		rc.left = pBitBlt->xDest ;
		rc.top = pBitBlt->yDest ;
		rc.right = pBitBlt->xDest + pBitBlt->cxDest ;
		rc.bottom = pBitBlt->yDest + pBitBlt->cyDest ;

		FillRect( m_hDCMem , &rc , (HBRUSH)GetCurrentObject(m_hDCMem , OBJ_BRUSH ) ) ;
	}
	TRACE("EmrBitBlt\n");

}
void CEmfReaderDlg::EmrStretchDibits( LPBYTE lpData)
{
	PEMRSTRETCHDIBITS pStretchDibts ;

	pStretchDibts = (PEMRSTRETCHDIBITS)lpData ;
	PBITMAPINFO pBitmapInfo = (PBITMAPINFO)( lpData + pStretchDibts->offBmiSrc ) ; 
	if( pStretchDibts->offBmiSrc > 0 )
	{
		int nOldMode = SetStretchBltMode( m_hDCMem, STRETCH_HALFTONE); 
		HDC hNewDC = CreateCompatibleDC( m_hDCMem ) ;
		LPVOID lpDib = lpData + pStretchDibts->offBitsSrc ;

		{
			BOOL bRet = StretchDIBits( m_hDCMem , pStretchDibts->xDest , pStretchDibts->yDest , pStretchDibts->cxDest , pStretchDibts->cyDest , 
				pStretchDibts->xSrc , pStretchDibts->ySrc  ,pStretchDibts->cxSrc , pStretchDibts->cySrc ,
				lpData + pStretchDibts->offBitsSrc , 
				pBitmapInfo , 
				pStretchDibts->iUsageSrc ,pStretchDibts->dwRop ) ;

		}
		SetStretchBltMode( m_hDCMem, nOldMode); 

		//if( pStretchDibts->offBitsSrc && pBitmapInfo->bmiHeader.biSizeImage == 0 )
		//{
		//	pBitmapInfo->bmiHeader.biSizeImage = pStretchDibts->cbBitsSrc  ;
		//}
		//if(  pStretchDibts->offBitsSrc && pBitmapInfo->bmiHeader.biSizeImage&&pStretchDibts->cbBitsSrc )
		//	WriteToBMPFile( m_strEmfFile , m_dwEmfRecord , pBitmapInfo , lpData + pStretchDibts->offBitsSrc  ) ;

	}
	else
	{
		TRACE("EmrStretchDibits,bmt size is zero");
	}
	TRACE("EmrStretchDibits,dest:(%d,%d,%d,%d),src:(%d,%d,%d,%d),size:%ld\n",
		pStretchDibts->xDest , pStretchDibts->yDest , pStretchDibts->cxDest , pStretchDibts->cyDest , 
		pStretchDibts->xSrc , pStretchDibts->ySrc  , pStretchDibts->cxSrc , pStretchDibts->cySrc,
		pStretchDibts->emr.nSize 
		);
}
void CEmfReaderDlg::EmrExtTextOutW( LPBYTE lpData)
{
	PEMREXTTEXTOUTW pTextOut ;
	pTextOut = (PEMREXTTEXTOUTW)lpData ;
	TRACE(L"EmrExtTextOutW\n");
	RECT rect ;
	rect.left = pTextOut->emrtext.rcl.left ;
	rect.top = pTextOut->emrtext.rcl.top ;
	rect.right = pTextOut->emrtext.rcl.right ;
	rect.bottom = pTextOut->emrtext.rcl.bottom ;
	if( pTextOut->emr.iType == EMR_EXTTEXTOUTW )
	{
		BOOL bRet = ExtTextOutW( m_hDCMem , pTextOut->emrtext.ptlReference.x ,  pTextOut->emrtext.ptlReference.y , 
			pTextOut->emrtext.fOptions , &rect , 
			(LPWSTR)((BYTE *)lpData + pTextOut->emrtext.offString ), 
			pTextOut->emrtext.nChars ,(INT*)((BYTE *)lpData + pTextOut->emrtext.offDx )) ;

	}
	else
	{
		BOOL bRet = ExtTextOutA( m_hDCMem , pTextOut->emrtext.ptlReference.x ,  pTextOut->emrtext.ptlReference.y , 
			pTextOut->emrtext.fOptions , &rect , 
			(LPSTR)lpData + pTextOut->emrtext.offString , 
			pTextOut->emrtext.nChars ,(INT*)lpData + pTextOut->emrtext.offDx ) ;

	}
}


void CEmfReaderDlg::EmrDC(LPBYTE lpData) 
{
	PEMRABORTPATH pEmr = (PEMRABORTPATH)lpData ;
	switch( pEmr->emr.iType )
	{
	case EMR_ABORTPATH:
		TRACE("EmrAbortPath\n");
		break ;
	case EMR_BEGINPATH:
		BeginPath( m_hDCMem ) ;
		TRACE("EmrBeginPath\n");
		break ;
	case EMR_ENDPATH:
		EndPath( m_hDCMem ) ;
		TRACE("EmrEndPath\n");
		break ;
	case EMR_CLOSEFIGURE:
		CloseFigure( m_hDCMem ) ;
		TRACE("EmrCloseFigure\n");
		break ;
	case EMR_FLATTENPATH:
		FlattenPath( m_hDCMem ) ;
		TRACE("EmrFlattenPath\n");
		break ;
	case EMR_WIDENPATH:
		WidenPath( m_hDCMem ) ;
		TRACE("EmrWidenPath\n");
		break ;
	case EMR_SETMETARGN:
		SetMetaRgn( m_hDCMem ) ;
		TRACE("EmrSetMetargn\n");
		break ;
	case EMR_SAVEDC:
		SaveDC( m_hDCMem ) ;
		TRACE("EmrSaveDC\n");
		break ;
	case EMR_REALIZEPALETTE:
		RealizePalette( m_hDCMem ) ;
		TRACE("EmrRealizePalette\n");
		break ;

	}
}
void CEmfReaderDlg::EmrRestoreDC(LPBYTE lpData) 
{
	PEMRRESTOREDC pRestoreDC = (PEMRRESTOREDC)lpData ;
	RestoreDC( m_hDCMem , pRestoreDC->iRelative ) ;
	TRACE("EmrRestoreDC:%ld\n" , pRestoreDC->iRelative ) ;
}
void CEmfReaderDlg::EmrMoveX(LPBYTE lpData) 
{
	PEMRLINETO pLineTo = (PEMRLINETO)lpData ;
	switch( pLineTo->emr.iType )
	{
	case EMR_MOVETOEX:
		POINT pt ;
		MoveToEx( m_hDCMem , pLineTo->ptl.x , pLineTo->ptl.y , &pt ) ;
		TRACE("EmrMoveToEX,x:%ld,y:%ld\n",pLineTo->ptl.x,pLineTo->ptl.y);
		break ;
	case EMR_LINETO:
		LineTo( m_hDCMem , pLineTo->ptl.x , pLineTo->ptl.y ) ;
		TRACE("EmrLineTo,x:%ld,y:%ld\n",pLineTo->ptl.x,pLineTo->ptl.y);
		break ;
	}
}

void CEmfReaderDlg::EmrSetBkOrTextColor(LPBYTE lpData ) 
{
	PEMRSETBKCOLOR pColor = (PEMRSETBKCOLOR)lpData ;
	switch( pColor->emr.iType )
	{
	case EMR_SETBKCOLOR:
		TRACE("EmrSetBkColor,r:%ld,g:%ld,b:%ld\n",GetRValue(pColor->crColor),GetGValue(pColor->crColor),GetBValue(pColor->crColor) );
		SetBkColor( m_hDCMem , pColor->crColor ) ;
		break ;
	case EMR_SETTEXTCOLOR:
		SetTextColor( m_hDCMem , pColor->crColor ) ;
		TRACE("EmrSetTextColor,r:%ld,g:%ld,b:%ld\n",GetRValue(pColor->crColor),GetGValue(pColor->crColor),GetBValue(pColor->crColor) );
		break ;
	}

}
void CEmfReaderDlg::EmrSetBkOrOtherMode(LPBYTE lpData ) 
{
	PEMRSETBKMODE pMode = (PEMRSETBKMODE)lpData ;
	switch( pMode->emr.iType )
	{
	case EMR_SELECTCLIPPATH:
		SelectClipPath( m_hDCMem , pMode->iMode ) ;
		TRACE("EmrSelectClipPath,mode:%ld\n",pMode->iMode);
		break ;
	case EMR_SETBKMODE:
		SetBkMode( m_hDCMem , pMode->iMode ) ;
		TRACE("EmrSetBkMode,mode:%ld\n",pMode->iMode);
		break ;
	case EMR_SETMAPMODE:
		SetMapMode( m_hDCMem , pMode->iMode ) ;
		TRACE("EmrSetMapMode,mode:%ld\n",pMode->iMode);
		break ;
	case EMR_SETPOLYFILLMODE:
		SetPolyFillMode( m_hDCMem , pMode->iMode ) ;
		TRACE("EmrSetPollyFillMode,mode:%ld\n",pMode->iMode);
		break ;
	case EMR_SETROP2:
		SetROP2( m_hDCMem , pMode->iMode ) ;
		TRACE("EmrSetROP2,mode:%ld\n",pMode->iMode);
		break ;
	case EMR_SETSTRETCHBLTMODE:
		SetStretchBltMode( m_hDCMem , pMode->iMode ) ;
		TRACE("EmrSetStretchBltMode,mode:%ld\n",pMode->iMode);
		break ;
	case EMR_SETTEXTALIGN:
		SetTextAlign( m_hDCMem , pMode->iMode ) ;
		TRACE("EmrSetTextAlign,mode:%ld\n",pMode->iMode);
		break ;
	case EMR_SETICMMODE:
		SetICMMode( m_hDCMem , pMode->iMode ) ;
		TRACE("EmrSetICMMode,mode:%ld\n",pMode->iMode);
		break ;
	case EMR_SETLAYOUT:
		SetLayout( m_hDCMem , pMode->iMode ) ;
		TRACE("EmrSetLayout,mode:%ld\n",pMode->iMode);
		break ;
	}

}
void CEmfReaderDlg::EmrSetWindowOrViewPortExtEX(LPBYTE lpData ) 
{
	PEMRSETWINDOWEXTEX pWindowExt = (PEMRSETWINDOWEXTEX)lpData ;
	SIZE  sz ; 
	switch( pWindowExt->emr.iType )
	{
	case EMR_SETWINDOWEXTEX:
		SetWindowExtEx( m_hDCMem , pWindowExt->szlExtent.cx , pWindowExt->szlExtent.cy , &sz ) ;
		TRACE("EmrSetWindowExtEx,x:%ld,y:%ld\n",pWindowExt->szlExtent.cx,pWindowExt->szlExtent.cy);
		break ;
	case EMR_SETVIEWPORTEXTEX:
		SetViewportExtEx( m_hDCMem , pWindowExt->szlExtent.cx , pWindowExt->szlExtent.cy , &sz ) ;
		TRACE("EmrSetViewPortExtEx,x:%ld,y:%ld\n",pWindowExt->szlExtent.cx,pWindowExt->szlExtent.cy);
		break ;
	}

}
void CEmfReaderDlg::EmrSetWindowOrViewPortEX(LPBYTE lpData ) 
{
	PEMRSETWINDOWORGEX pWindowEx = (PEMRSETWINDOWORGEX)lpData ;
	POINT pt ;
	switch( pWindowEx->emr.iType )
	{
	case EMR_SETWINDOWORGEX:
		SetWindowOrgEx( m_hDCMem , pWindowEx->ptlOrigin.x , pWindowEx->ptlOrigin.y , &pt ) ;
		TRACE("EmrSetWindowOrgEx,x:%ld,y:%ld\n",pWindowEx->ptlOrigin.x,pWindowEx->ptlOrigin.y);
		break ;
	case EMR_SETVIEWPORTORGEX:
		SetViewportOrgEx( m_hDCMem , pWindowEx->ptlOrigin.x , pWindowEx->ptlOrigin.y  , &pt ) ;
		TRACE("EmrSetViewPortOrgEx,x:%ld,y:%ld\n",pWindowEx->ptlOrigin.x,pWindowEx->ptlOrigin.y);
		break ;
	case EMR_SETBRUSHORGEX:
		SetBrushOrgEx( m_hDCMem , pWindowEx->ptlOrigin.x , pWindowEx->ptlOrigin.y  , &pt ) ;
		TRACE("EmrSetBrushOrgEx,x:%ld,y:%ld\n",pWindowEx->ptlOrigin.x,pWindowEx->ptlOrigin.y);
		break ;
	}

}
void CEmfReaderDlg::EmrSetColorSpace( LPBYTE lpData ) 
{
	PEMRSETCOLORSPACE pColorSpace = (PEMRSETCOLORSPACE)lpData ;
	switch( pColorSpace->emr.iType )
	{
	case EMR_SETCOLORSPACE:
		//SetColorSpace( m_hDCMem , pColorSpace->ihCS ) ;
		TRACE("SetColorSpace,:%ld\n",pColorSpace->ihCS );
		break ;
		//case EMR_SELECTCOLORSPACE:
		//	SetViewportOrgEx( m_hDCMem , pWindowEx->ptlOrigin.x , pWindowEx->ptlOrigin.y  , &pt ) ;
		//	TRACE("EmrSetViewPortOrgEx,x:%ld,y:%ld\n",pWindowEx->ptlOrigin.x,pWindowEx->ptlOrigin.y);
		//	break ;
	case EMR_DELETECOLORSPACE:
		//DeleteColorSpace( pColorSpace->ihCS ) ;
		TRACE("DeleteColorSpace,:%ld\n",pColorSpace->ihCS );
		break ;
	}
}
void CEmfReaderDlg::EmrExtCreateFontIndirectW( LPBYTE lpData ) 
{
	PEMREXTCREATEFONTINDIRECTW pFont = (PEMREXTCREATEFONTINDIRECTW)lpData ;
	HFONT hFont = CreateFontIndirectW( & pFont->elfw.elfLogFont ) ;
	if( hFont )
	{
		HGDIOBJECT_NODE node ;
		node.dwIndex = pFont->ihFont ;
		node.hGidObj = hFont ;
		CString strFont ;
		strFont.Format(  _T("FONT:0x%08x") , pFont->ihFont ) ;
		_tcscpy( node.szDescript , strFont.GetBuffer() ) ;
		m_listGdiObj.push_back( node ) ;
	}
	CString strHint ;
	strHint.Format( _T("EmrExtCreateFontIndirectW,ihFont:%ld,%s\n") , pFont->ihFont ,pFont->elfw.elfLogFont.lfFaceName ) ;
	TRACE(strHint);
}

void CEmfReaderDlg::EmrCreateBrushIndirect(LPBYTE lpData ) 
{
	PEMRCREATEBRUSHINDIRECT pBrushIndirect ;
	pBrushIndirect = (PEMRCREATEBRUSHINDIRECT)lpData ;
	LOGBRUSH lgBrush ; 
	lgBrush.lbColor = pBrushIndirect->lb.lbColor ;
	lgBrush.lbHatch = pBrushIndirect->lb.lbHatch ;
	lgBrush.lbStyle = pBrushIndirect->lb.lbStyle ;
	HBRUSH hBrush = CreateBrushIndirect( &lgBrush ) ;
	if( hBrush )
	{
		HGDIOBJECT_NODE node ;
		node.dwIndex = pBrushIndirect->ihBrush ;
		node.hGidObj = hBrush ;
		CString strBrush ;
		strBrush.Format(  _T("BRUSH:0x%08x") , pBrushIndirect->ihBrush ) ;
		_tcscpy( node.szDescript , strBrush.GetBuffer() ) ;
		m_listGdiObj.push_back( node ) ;
	}
	TRACE( _T("EmrCreateBrushIndirect:0x%08x r:%x,g:%x,b:%x\n") , pBrushIndirect->ihBrush , GetRValue( lgBrush.lbColor ) ,  GetGValue( lgBrush.lbColor ) , GetBValue( lgBrush.lbColor ) ) ;
}
void CEmfReaderDlg::EmrCreatePen( LPBYTE lpData ) 
{
	PEMRCREATEPEN pPen = (PEMRCREATEPEN) lpData ;
	HPEN hPen = CreatePen( pPen->lopn.lopnStyle , pPen->lopn.lopnWidth.x , pPen->lopn.lopnColor ) ;
	if( hPen )
	{
		HGDIOBJECT_NODE node ;
		node.dwIndex = pPen->ihPen ;
		node.hGidObj = hPen ;
		CString strBrush ;
		strBrush.Format(  _T("PEN:0x%08x") , pPen->ihPen ) ;
		_tcscpy( node.szDescript , strBrush.GetBuffer() ) ;
		m_listGdiObj.push_back( node ) ;
	}
	TRACE( _T("EmrExtCreatePen:0x%08x r:%x,g:%x,b:%x\n") , pPen->ihPen , GetRValue( pPen->lopn.lopnColor ) ,  GetGValue( pPen->lopn.lopnColor ) , GetBValue( pPen->lopn.lopnColor ) ) ;
}

void CEmfReaderDlg::EmrExtCreatePen(LPBYTE lpData )
{
	PEMREXTCREATEPEN pPen ;
	pPen = (PEMREXTCREATEPEN)lpData ;
	LOGBRUSH lgBrush ; 
	lgBrush.lbStyle = pPen->elp.elpBrushStyle ;
	lgBrush.lbColor = pPen->elp.elpColor ;
	lgBrush.lbHatch = pPen->elp.elpHatch;

	HPEN hPen = ExtCreatePen( pPen->elp.elpPenStyle , pPen->elp.elpWidth ,  &lgBrush , pPen->elp.elpNumEntries , ( pPen->elp.elpNumEntries == 0 ? NULL : pPen->elp.elpStyleEntry ) ) ;
	if( hPen )
	{
		HGDIOBJECT_NODE node ;
		node.dwIndex = pPen->ihPen ;
		node.hGidObj = hPen ;
		CString strBrush ;
		strBrush.Format(  _T("exPEN:0x%08x") , pPen->ihPen ) ;
		_tcscpy( node.szDescript , strBrush.GetBuffer() ) ;
		m_listGdiObj.push_back( node ) ;
	}
	else
	{
		DWORD dwError = GetLastError() ;
		TRACE( _T("EmrExtCreatePen.Error:0x%08x r:%x,g:%x,b:%x\n") , dwError , GetRValue( lgBrush.lbColor ) ,  GetGValue( lgBrush.lbColor ) , GetBValue( lgBrush.lbColor ) ) ;
	}
	TRACE( _T("EmrExtCreatePen:0x%08x r:%x,g:%x,b:%x\n") , pPen->ihPen , GetRValue( lgBrush.lbColor ) ,  GetGValue( lgBrush.lbColor ) , GetBValue( lgBrush.lbColor ) ) ;

}
void CEmfReaderDlg::EmrModifyWorldTransForm( LPBYTE lpData ) 
{
	PEMRMODIFYWORLDTRANSFORM pTransForm = (PEMRMODIFYWORLDTRANSFORM)lpData ;
	ModifyWorldTransform( m_hDCMem , &pTransForm->xform , pTransForm->iMode ) ;
	TRACE(_T("EmrModifyWorldTransForm:0x%08x\n"),pTransForm->iMode) ;
}
void CEmfReaderDlg::EmrExtSelectClipRgn( LPBYTE lpData ) 
{
	PEMREXTSELECTCLIPRGN pRgn = (PEMREXTSELECTCLIPRGN)lpData;
	RGNDATA *pRgnData ;
	pRgnData = (RGNDATA *)pRgn->RgnData ;
	HRGN hRgn = ExtCreateRegion( NULL , pRgn->cbRgnData , pRgnData ) ;
	if( hRgn )
		ExtSelectClipRgn( m_hDCMem , hRgn , pRgn->iMode ) ;
	else
		ExtSelectClipRgn( m_hDCMem , NULL , pRgn->iMode ) ;
	TRACE(_T("EmrExtSelectClipRgn\n"));
}
void CEmfReaderDlg::EmrInterSelectClipRect( LPBYTE lpData ) 
{
	PEMRINTERSECTCLIPRECT pClipRect = (PEMRINTERSECTCLIPRECT)lpData ;
	switch( pClipRect->emr.iType )
	{
		case EMR_INTERSECTCLIPRECT:
			IntersectClipRect( m_hDCMem , pClipRect->rclClip.left , pClipRect->rclClip.top , pClipRect->rclClip.right , pClipRect->rclClip.bottom ) ;
			TRACE(_T("IntersectClipRect:%d,%d,%d,%d\n") , pClipRect->rclClip.left , pClipRect->rclClip.top , pClipRect->rclClip.right , pClipRect->rclClip.bottom ) ;
			break ;
		case EMR_EXCLUDECLIPRECT:
			ExcludeClipRect(m_hDCMem , pClipRect->rclClip.left , pClipRect->rclClip.top , pClipRect->rclClip.right , pClipRect->rclClip.bottom ) ;
			TRACE(_T("ExcludeClipRect:%d,%d,%d,%d\n") , pClipRect->rclClip.left , pClipRect->rclClip.top , pClipRect->rclClip.right , pClipRect->rclClip.bottom ) ;
			break ;
	}
}
void CEmfReaderDlg::EmrStrokePath( LPBYTE lpData ) 
{
	PEMRFILLPATH pPath = (PEMRFILLPATH)lpData ;
	switch( pPath->emr.iType )
	{
	case EMR_FILLPATH:
		FillPath( m_hDCMem ) ;
		TRACE(_T("m_hDCMem\n")) ;
		break ;
	case EMR_STROKEANDFILLPATH:
		StrokeAndFillPath( m_hDCMem ) ;
		TRACE(_T("StrokeAndFillPath\n")) ;
		break ;
	case EMR_STROKEPATH:
		StrokePath( m_hDCMem ) ;
		TRACE(_T("StrokeAndFillPath\n")) ;
		break ;
	}
}
void CEmfReaderDlg::EmrPolyPolyLine16( LPBYTE lpData ) 
{
	PEMRPOLYPOLYLINE16 pLine = (PEMRPOLYPOLYLINE16)lpData ;
	POINT *pPoints = new POINT[pLine->cpts];
	INT *lpPolyCounts = new INT[pLine->cpts];
	for( long lIndex = 0 ; lIndex < (long)pLine->cpts ; lIndex++ )
	{
		pPoints[lIndex].x = pLine->apts[lIndex].x ;
		pPoints[lIndex].y = pLine->apts[lIndex].y ;
		lpPolyCounts[lIndex] = pLine->aPolyCounts[lIndex] ;
	}
	switch( pLine->emr.iType )
	{
	case EMR_POLYPOLYLINE16:
		PolyPolyline( m_hDCMem , pPoints , pLine->aPolyCounts , pLine->cpts );
		TRACE(_T("EMR_POLYPOLYLINE16:%d\n"),pLine->cpts  ) ;
		break ;
	case EMR_POLYPOLYGON16:
		PolyPolygon( m_hDCMem , pPoints , lpPolyCounts , pLine->cpts );
		TRACE(_T("EMR_POLYPOLYGON16:%d\n"),pLine->cpts  ) ;
		break ;
	}
	delete lpPolyCounts ;
	delete pPoints ;

}
void CEmfReaderDlg::EmrPolyPolyLine( LPBYTE lpData ) 
{
	PEMRPOLYPOLYLINE pLine = (PEMRPOLYPOLYLINE)lpData ;
	POINT *pPoints = new POINT[pLine->cptl];
	INT *lpPolyCounts = new INT[pLine->cptl];
	for( long lIndex = 0 ; lIndex < (long)pLine->cptl ; lIndex++ )
	{
		pPoints[lIndex].x = pLine->aptl[lIndex].x ;
		pPoints[lIndex].y = pLine->aptl[lIndex].y ;
		lpPolyCounts[lIndex] = pLine->aPolyCounts[lIndex] ;
	}
	switch( pLine->emr.iType )
	{
	case EMR_POLYPOLYLINE16:
		PolyPolyline( m_hDCMem , pPoints , pLine->aPolyCounts , pLine->cptl );
		TRACE(_T("EMR_POLYPOLYLINE:%d\n"),pLine->cptl  ) ;
		break ;
	case EMR_POLYPOLYGON16:
		PolyPolygon( m_hDCMem , pPoints ,lpPolyCounts , pLine->cptl );
		TRACE(_T("EMR_POLYPOLYGON:%d\n"),pLine->cptl  ) ;
		break ;
	}
	delete lpPolyCounts ;
	delete pPoints ;

}
void CEmfReaderDlg::EmrAngleArc( LPBYTE lpData ) 
{
	PEMRANGLEARC pArc = (PEMRANGLEARC)lpData ;
	AngleArc( m_hDCMem , pArc->ptlCenter.x , pArc->ptlCenter.y , pArc->nRadius , pArc->eStartAngle , pArc->eSweepAngle ) ;
	TRACE(_T("AngleArc,x:%d,y:%d,radius:%d,start:%d,sweep:%d\n"), pArc->ptlCenter.x , pArc->ptlCenter.y , pArc->nRadius , pArc->eStartAngle , pArc->eSweepAngle);
}
void CEmfReaderDlg::EmrRectangle( LPBYTE lpData ) 
{
	PEMRRECTANGLE pRectangle = (PEMRRECTANGLE)lpData ;
	switch( pRectangle->emr.iType )
	{
	case EMR_ELLIPSE:
		Ellipse( m_hDCMem , pRectangle->rclBox.left , pRectangle->rclBox.top , pRectangle->rclBox.right, pRectangle->rclBox.bottom ) ;
		TRACE(_T("Ellipse:%d,%d,%d,%d\n"), pRectangle->rclBox.left , pRectangle->rclBox.top , pRectangle->rclBox.right, pRectangle->rclBox.bottom);
		break ;
	case EMR_RECTANGLE:
		Rectangle( m_hDCMem , pRectangle->rclBox.left , pRectangle->rclBox.top , pRectangle->rclBox.right, pRectangle->rclBox.bottom ) ;
		TRACE(_T("Rectangle:%d,%d,%d,%d\n"), pRectangle->rclBox.left , pRectangle->rclBox.top , pRectangle->rclBox.right, pRectangle->rclBox.bottom);
	}

}
void CEmfReaderDlg::EmrRoundRect( LPBYTE lpData ) 
{
	PEMRROUNDRECT pRoundRect = (PEMRROUNDRECT)lpData ;
	RoundRect( m_hDCMem , pRoundRect->rclBox.left , pRoundRect->rclBox.top , pRoundRect->rclBox.right , pRoundRect->rclBox.bottom ,
				pRoundRect->szlCorner.cx , pRoundRect->szlCorner.cy 
		) ;
	TRACE(_T("RoundRect:%d,%d,%d,%d\n"), pRoundRect->rclBox.left , pRoundRect->rclBox.top , pRoundRect->rclBox.right, pRoundRect->rclBox.bottom);

}
void CEmfReaderDlg::EmrArc( LPBYTE lpData ) 
{
	PEMRARC pArc = (PEMRARC)lpData ;
	switch( pArc->emr.iType )
	{
	case EMR_ARC:
		Arc( m_hDCMem , pArc->rclBox.left , pArc->rclBox.top , pArc->rclBox.right, pArc->rclBox.bottom , pArc->ptlStart.x , pArc->ptlStart.y , pArc->ptlEnd.x , pArc->ptlEnd.y  ) ;
		TRACE(_T("Arc:%d,%d,%d,%d,%d,%d,%d,%d\n"), pArc->rclBox.left , pArc->rclBox.top , pArc->rclBox.right, pArc->rclBox.bottom , pArc->ptlStart.x , pArc->ptlStart.y , pArc->ptlEnd.x , pArc->ptlEnd.y  ) ;
	case EMR_CHORD:
		Chord( m_hDCMem , pArc->rclBox.left , pArc->rclBox.top , pArc->rclBox.right, pArc->rclBox.bottom , pArc->ptlStart.x , pArc->ptlStart.y , pArc->ptlEnd.x , pArc->ptlEnd.y  ) ;
		TRACE(_T("Chord:%d,%d,%d,%d,%d,%d,%d,%d\n"), pArc->rclBox.left , pArc->rclBox.top , pArc->rclBox.right, pArc->rclBox.bottom , pArc->ptlStart.x , pArc->ptlStart.y , pArc->ptlEnd.x , pArc->ptlEnd.y  ) ;
	case EMR_ARCTO:
		ArcTo( m_hDCMem , pArc->rclBox.left , pArc->rclBox.top , pArc->rclBox.right, pArc->rclBox.bottom , pArc->ptlStart.x , pArc->ptlStart.y , pArc->ptlEnd.x , pArc->ptlEnd.y  ) ;
		TRACE(_T("ArcTo:%d,%d,%d,%d,%d,%d,%d,%d\n"), pArc->rclBox.left , pArc->rclBox.top , pArc->rclBox.right, pArc->rclBox.bottom , pArc->ptlStart.x , pArc->ptlStart.y , pArc->ptlEnd.x , pArc->ptlEnd.y  ) ;
	case EMR_PIE:
		Pie( m_hDCMem , pArc->rclBox.left , pArc->rclBox.top , pArc->rclBox.right, pArc->rclBox.bottom , pArc->ptlStart.x , pArc->ptlStart.y , pArc->ptlEnd.x , pArc->ptlEnd.y  ) ;
		TRACE(_T("Pie:%d,%d,%d,%d,%d,%d,%d,%d\n"), pArc->rclBox.left , pArc->rclBox.top , pArc->rclBox.right, pArc->rclBox.bottom , pArc->ptlStart.x , pArc->ptlStart.y , pArc->ptlEnd.x , pArc->ptlEnd.y  ) ;

	}

}

void CEmfReaderDlg::EmrFillRgn( LPBYTE lpData ) 
{
	PEMRFILLRGN pFillRgn = (PEMRFILLRGN)lpData; 
	HRGN hRgn = ExtCreateRegion( NULL , pFillRgn->cbRgnData , (RGNDATA*)pFillRgn->RgnData );
	if( hRgn )
	{
		HBRUSH hBrush ;
		{
			hBrush = (HBRUSH)GetStockObject( pFillRgn->ihBrush & 0xFF  ) ;
			if( hBrush )
			{
				FillRgn( m_hDCMem , hRgn , hBrush ) ;
			}
		}		
		DeleteObject( hRgn ) ;
	}
	TRACE( _T("EmrFillRgn\n") ) ;
}